#ifndef _SYS_IN_STREAM_H_
#define _SYS_IN_STREAM_H_

#include "FanObj.h"
#include "SysTypes.h"

#define IN_STREAM_VTABLE(self)   ((InStreamVTable*)((FanObj*)self)->vtable)


extern Type*    InStream_classType;
extern VTable*  InStream_classVTable;


/* [sys::InStream] Attributes */
struct InStream
{
  FanObj        super;
  InStream*     in;
  Bool          bigEndian;
  Charset*      charset;
};


/* [sys::InStream] Virtual-table */
typedef struct InStreamVTable
{
  FanObjVTable  super;
  Bool          (*close)(InStream* self);
  NullableInt   (*read)(InStream* self);
  NullableInt   (*readBuf)(InStream* self, Buf* buf, Int n);
  Int           (*skip)(InStream* self, Int n);
  InStream*     (*unread)(InStream* self, Int b);

  /* Internal virtual methods */
  NullableInt  (*readChar)(InStream* self);
  InStream*    (*unreadChar)(InStream* self, Int b);
} InStreamVTable;


/* [sys::InStream] Methods and fields */
void            InStream_make(InStream* self, InStream* in);
Endian*         InStream_endian(InStream* self);
void            InStream_setEndian(InStream* self, Endian* val);
Charset*        InStream_charset(InStream* self);
void            InStream_setCharset(InStream* self, Charset* val);
NullableInt     InStream_read(InStream* self);
NullableInt     InStream_readBuf(InStream* self, Buf* buf, Int n);
InStream*       InStream_unread(InStream* self, Int b);
Bool            InStream_close(InStream* self);
Int             InStream_skip(InStream* self, Int n);
Buf*            InStream_readAllBuf(InStream* self);
Buf*            InStream_readBufFully(InStream* self, Buf* buf, Int n);
NullableInt     InStream_peek(InStream* self);
Int             InStream_readU1(InStream* self);
Int             InStream_readS1(InStream* self);
Int             InStream_readU2(InStream* self);
Int             InStream_readS2(InStream* self);
Int             InStream_readU4(InStream* self);
Int             InStream_readS4(InStream* self);
Int             InStream_readS8(InStream* self);
Float           InStream_readF4(InStream* self);
Float           InStream_readF8(InStream* self);
Bool            InStream_readBool(InStream* self);
Decimal*        InStream_readDecimal(InStream* self);
Str*            InStream_readUtf(InStream* self);
NullableInt     InStream_readChar(InStream* self);
InStream*       InStream_unreadChar(InStream* self, Int b);
NullableInt     InStream_peekChar(InStream* self);
Str*            InStream_readChars(InStream* self, Int n);
Str*            InStream_readLine_0(InStream* self);
Str*            InStream_readLine(InStream* self, NullableInt max);
Str*            InStream_readStrToken_0(InStream* self);
Str*            InStream_readStrToken_1(InStream* self, NullableInt max);
Str*            InStream_readStrToken(InStream* self, NullableInt max, Func* c);
List*           InStream_readAllLines(InStream* self);
void            InStream_eachLine(InStream* self, Func* f);
Str*            InStream_readAllStr_0(InStream* self);
Str*            InStream_readAllStr(InStream* self, Bool normalizeNewlines);
NullableObj     InStream_readObj_0(InStream* self);
NullableObj     InStream_readObj(InStream* self, Map* options);
Map*            InStream_readProps(InStream* self);
Int             InStream_pipe_1(InStream* self, OutStream* out);
Int             InStream_pipe_2(InStream* self, OutStream* out, NullableInt n);
Int             InStream_pipe(InStream* self, OutStream* out, NullableInt n, Bool close);


/* [sys::InStream] Type-system functions */
Type*           InStream_initType(void);
VTable*         InStream_initVTable(void);
void            InStream_initStatic(void);


#endif
